package com.my.controller;

import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonSerializer;
import com.my.pojo.Business;
import com.my.pojo.Goods;
import com.my.service.IGoodsService;
import com.my.util.JWTUtils;
import com.my.util.UserJWTUtils;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@CrossOrigin("*")
@RequestMapping("/goods")
public class GoodsController {
    private IGoodsService iGoodsService;

    @Autowired
    public void setGoodsService(IGoodsService iGoodsService) {
        this.iGoodsService = iGoodsService;
    }

    RedisTemplate<String, String> redisTemplate;

    @Autowired
    public void setRedisTemplate(RedisTemplate<String, String> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    //TODO:写一个按照ID查询的方法

    private String listGoodsToJSON(List<Goods> goodsList) {
        JsonArray jsonArray = new JsonArray();
        goodsList.forEach(e -> {
            JsonObject jsonObject = new JsonObject();
            jsonObject.addProperty("goodsId", e.getGoodsId());
            jsonObject.addProperty("name", e.getName());
            jsonObject.addProperty("price", e.getPrice());
            jsonObject.addProperty("img", e.getImgUrl());
            jsonObject.addProperty("stock", e.getStock());
            jsonObject.addProperty("info", e.getInfo());
            jsonObject.addProperty("status", e.getStatus());
            jsonArray.add(jsonObject);
        });
        return jsonArray.toString();
    }

    private void putMessage(Map<String, String> map, String code, String message) {
        map.put("code", code);
        map.put("message", message);
    }

    /**
     * 添加商品
     *
     * @param name   商品名称
     * @param price  价格
     * @param imgUrl 图片链接
     * @param stock  库存
     * @param info   描述
     * @return 状态码+信息
     * 状态码：
     * add_200 成功
     * add_500 空文本
     * add_501 价格<=0或库存<0
     * add_502 未找到商铺
     * add_503 sql报错
     */
    @RequestMapping("/add")
    public String addGoods(String name, Double price, String imgUrl, Integer stock, String info, HttpServletRequest req) {
        String token = req.getHeader("token");
        Integer businessId = JWTUtils.getId(token);
        Map<String, String> map = new HashMap<>();
        if (businessId == null) {
            this.putMessage(map, "504", "token解析失败");
        } else {
            if ("".equals(name.trim()) || "".equals(imgUrl) || "".equals(info)) {
                this.putMessage(map, "add_500", "empty text");
            } else if (price <= 0 || stock < 0) {
                this.putMessage(map, "add_501", "error value");
            } else {
                Goods goods = new Goods();
                goods.setName(name);
                goods.setPrice(price);
                goods.setImgUrl(imgUrl);
                goods.setStock(stock);
                goods.setInfo(info);
                goods.setStatus(0);
                Business business = new Business();
                business.setBusinessId(businessId);
                goods.setBusiness(business);
                System.out.println(goods.getBusiness().getBusinessId());
                Integer res = iGoodsService.addGoods(goods);
                if (res == -1) {
                    this.putMessage(map, "add_502", "businessId no found");
                } else if (res == -2) {
                    this.putMessage(map, "add_503", "sql error");
                } else if (res > 0) {
                    this.putMessage(map, "200", "success");
                }
            }
        }
        return new Gson().toJson(map);
    }

    /**
     * 删除商品
     *
     * @param goodsId
     * @return 状态码+信息
     * 状态码：
     * delete_200  成功
     * delete_500  错误
     */
    @RequestMapping("/delete")
    public String deleteGoods(Integer goodsId) {
        Map<String, String> map = new HashMap<>();

        Integer res = iGoodsService.deleteGoods(goodsId);
        if (res == 1) {
            this.putMessage(map, "200", "success");
        } else if (res == 1) {
            this.putMessage(map, "delete_500", "error");
        }

        return new Gson().toJson(map);
    }

    @RequestMapping("/deleteGoods")
    public String deleteGoods(String goodsIds) {
        Map<String, String> map = new HashMap<>();
        List<Integer> list = JSONObject.parseArray(goodsIds, Integer.class);
        int count = 0;
        for (Integer i : list) {
            System.out.println(i);
            count = count + iGoodsService.deleteGoods(i);
        }
        System.out.println(count);
        if (count == list.size()) {
            this.putMessage(map, "200", "SUCCESS");
        } else {
            this.putMessage(map, "500", "ERROR");
        }
        return new Gson().toJson(map);
    }

    @RequestMapping("/reverse")
    public String reverseGoods(Integer goodsId) {
        Map<String, String> map = new HashMap<>();
        Integer res = iGoodsService.reverseGoods(goodsId);
        if (res == 0) {
            this.putMessage(map, "200", "success");
        } else if (res == 1) {
            this.putMessage(map, "delete_500", "error");
        }

        return new Gson().toJson(map);
    }

    /**
     * 修改商品信息
     *
     * @param name   商品名
     * @param price  价格
     * @param imgUrl 图片链接
     * @param stock  库存
     * @param info   描述
     * @return 状态码+信息
     * 状态码：
     * update_200  成功
     * update_500  空文本
     * update_501  错误数值
     * update_502  sql错误
     * update_502  sql错误
     */
    @RequestMapping("/update")
    public String updateGoods(Integer id, String name, Double price, String imgUrl, Integer stock, String info, HttpServletRequest req) {
        String token = req.getHeader("token");
        Integer businessId = JWTUtils.getId(token);
        Map<String, String> map = new HashMap<>();
        if (name.trim().equals("") || imgUrl.trim().equals("") || info.equals("")) {
            this.putMessage(map, "update_500", "empty text");
        } else if (price <= 0 || stock < 0) {
            this.putMessage(map, "update_501", "error value");
        } else {
            Goods goods = this.iGoodsService.selById(id);
            Integer ori_stock = goods.getStock();
            goods.setName(name);
            goods.setPrice(price);
            goods.setImgUrl(imgUrl);
            goods.setStock(stock);
            goods.setInfo(info);
            Business business = new Business();
            business.setBusinessId(businessId);
            goods.setBusiness(business);
            Integer res = iGoodsService.updateGoods(goods, ori_stock);
            if (res == -1) {
                this.putMessage(map, "update_502", "sql error");
            } else if (res == 0) {
                this.putMessage(map, "200", "success");
            }
        }
        return new Gson().toJson(map);
    }

    /**
     * 分页查询
     *
     * @param context     上下文
     * @param currentPage 当前页
     * @param pageSize    页大小
     * @param sort        排序规则
     * @param asc         true-升序/false-降序
     * @return 状态码+信息
     * 状态码：
     * 200 成功+分页数据
     * 500 失败
     */
    @RequestMapping("/show")
    public String showGoods(String context, Integer currentPage, Integer pageSize, String sort, Boolean asc, HttpServletRequest req) {
        String token = req.getHeader("token");
        Integer businessId = JWTUtils.getId(token);
        Map<String, String> map = new HashMap<>();
        Pageable pageable;
        if (!"".equals(sort)) {
            Sort.Order order = new Sort.Order((asc ? Sort.Direction.ASC : Sort.Direction.DESC), sort);
            Sort s = new Sort(order);
            pageable = new PageRequest(currentPage, pageSize, s);
        } else {
            pageable = new PageRequest(currentPage, pageSize);
        }

        Page<Goods> goodsPage = this.iGoodsService.showGoods(pageable, context, businessId);
        if (goodsPage.getContent().size() == 0) {
            this.putMessage(map, "404", "empty");
        } else {
            this.putMessage(map, "200", "success");
            map.put("totalNum", goodsPage.getTotalElements() + "");
            map.put("totalPages", goodsPage.getTotalPages() + "");
            map.put("goods", listGoodsToJSON(goodsPage.getContent()));
        }
        return new Gson().toJson(map);
    }

    @RequestMapping("/showForUser")
    public String showGoodsForUser(String context, Integer currentPage, Integer pageSize, String sort, Boolean asc) {
        Map<String, String> map = new HashMap<>();
        Pageable pageable;
        if (!"".equals(sort)) {
            Sort.Order order = new Sort.Order((asc ? Sort.Direction.ASC : Sort.Direction.DESC), sort);
            Sort s = new Sort(order);
            pageable = new PageRequest(currentPage, pageSize, s);
        } else {
            pageable = new PageRequest(currentPage, pageSize);
        }

        Page<Goods> goodsPage = this.iGoodsService.showGoods(pageable, context);
        if (goodsPage.getContent().size() == 0) {
            this.putMessage(map, "404", "empty");
        } else {
            this.putMessage(map, "200", "success");
            map.put("totalNum", goodsPage.getTotalElements() + "");
            map.put("totalPages", goodsPage.getTotalPages() + "");
            JsonArray jsonArray = new JsonArray();
            List<Goods> goodsList = goodsPage.getContent();
            goodsList.forEach(e -> {
                JsonObject jsonObject = new JsonObject();
                jsonObject.addProperty("goodsId", e.getGoodsId());
                jsonObject.addProperty("name", e.getName());
                jsonObject.addProperty("price", e.getPrice());
                jsonObject.addProperty("shopName", e.getBusiness().getShopName());
                jsonObject.addProperty("img", e.getImgUrl());
                jsonObject.addProperty("stock", e.getStock());
                jsonObject.addProperty("info", e.getInfo());
                jsonObject.addProperty("status", e.getStatus());
                jsonArray.add(jsonObject);
            });
            map.put("goods", jsonArray.toString());
        }
        return new Gson().toJson(map);
    }

    @RequestMapping("/buy")
    public String buy(Integer num, Integer goodsId, HttpServletRequest req) {
        Map<String, String> map = new HashMap<>();

        if (num <= 0) {
            putMessage(map, "500", "参数错误");
        } else {
            Integer userId = UserJWTUtils.getId(req.getHeader("token"));
            if (userId == null) {
                putMessage(map, "400", "token解析失败");
            } else {
                Integer res = iGoodsService.buyGoods(num, goodsId, userId);
                if (res == 1) {
                    putMessage(map, "200", "Success");
                } else if (res == -1) {
                    putMessage(map, "500", "商品不存在");
                } else if (res == -2) {
                    putMessage(map, "300", "库存不足");
                } else if (res == -3) {
                    putMessage(map, "501", "sql错误");
                } else {
                    putMessage(map, "502", "未知错误");
                }
            }
        }

        return new Gson().toJson(map);
    }

    @RequestMapping("/selById")
    public String selById(Integer id) {
        Map<String, String> map = new HashMap<>();
        System.out.println(id);
        Goods goods = this.iGoodsService.selById(id);
        if (goods != null) {
            this.putMessage(map, "200", "success");
            JsonObject jsonObject = new JsonObject();
            jsonObject.addProperty("goodsId", goods.getGoodsId());
            jsonObject.addProperty("name", goods.getName());
            jsonObject.addProperty("price", goods.getPrice());
            jsonObject.addProperty("img", goods.getImgUrl());
            jsonObject.addProperty("stock", goods.getStock());
            jsonObject.addProperty("info", goods.getInfo());
            jsonObject.addProperty("status", goods.getStatus());
            map.put("goods", jsonObject.toString());
        } else {
            this.putMessage(map, "500", "error");
        }
        return new Gson().toJson(map);
    }

}
